package edu.pitt.dbmi.odie.gapp.gwt.client.foundry;

import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.DSDataFormat;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent;
import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

public class ODIE_FoundryPanel extends VLayout {
	
	private static final String XPATH_CLS_PATTERN = "//data/classBean" ;
	private static final String XPATH_SUBCLS_PATTERN = "//entry/string[.='SubClass']/../list/classBean" ;
	private static final String XPATH_SUPERCLS_PATTERN = "//entry/string[.='SuperClass']/../list/classBean" ;
	
	private String currentOntologyId = null ;
	private String currentClsId = null ;
	
	private VLayout ontologyGroup = null ;
	
	private HLayout clsLayout = null ;
	private VLayout clsGroup = null ;
	private VLayout subClsGroup = null ;
	private VLayout superClsGroup = null ;

	public ODIE_FoundryPanel() {
		
		setLayoutMargin(5) ;
		
		ontologyGroup = buildOntologyGroup() ;
		addMember(ontologyGroup);
		
		buildClsGroups() ;
	}
	
	private VLayout buildOntologyGroup() {
		DataSource ontologyDataSource = null ;
		ontologyDataSource = buildOntologyDataSource() ;
		final ListGrid ontologyListGrid = buildListGrid() ;
		ontologyListGrid.setAutoFetchData(true) ;
		ontologyListGrid.setAlternateRecordStyles(true);
		ontologyListGrid.setShowAllRecords(true);
		ontologyListGrid.setSelectionType(SelectionStyle.SINGLE);
		ontologyListGrid.setCanSort(true) ;
		ontologyListGrid.addRecordDoubleClickHandler(buildOntologyDoubleClickListener());
		ontologyListGrid.setDataSource(ontologyDataSource) ;
		ontologyListGrid.setCanAcceptDrop(false) ;
		ontologyListGrid.setCanEdit(false) ;
		ontologyListGrid.setCanReorderRecords(false) ;
		ontologyListGrid.setCanFreezeFields(false) ;
		ontologyListGrid.setCanReorderFields(false) ;
		ontologyListGrid.setCanGroupBy(false) ;
		ontologyListGrid.setCanHover(true);
		ontologyListGrid.setCanSelectAll(false);
		ontologyListGrid.setCanSelectText(false) ;
		ontologyListGrid.setCanResizeFields(false) ;
		ontologyListGrid.setShowHeaderContextMenu(false) ;
		ontologyListGrid.setHoverWidth(300) ;
		ontologyListGrid.addDataArrivedHandler(new DataArrivedHandler() {
			public void onDataArrived(DataArrivedEvent event) {
				ontologyListGrid.setSortField("displayLabel") ;
				ontologyListGrid.sort() ;
				ontologyListGrid.setCanSort(false) ;
				ontologyListGrid.getField("description").setShowHover(true) ;
				ontologyListGrid.redraw();
			}}) ;
		ontologyGroup = new VLayout();
		ontologyGroup.setLayoutMargin(5) ;
		ontologyGroup.setIsGroup(true);
		ontologyGroup.setGroupTitle("Ontology Navigator");
		ontologyGroup.addMember(ontologyListGrid) ;
		return ontologyGroup ;
		
	}
	
	private DataSource buildOntologyDataSource() {
		
		DataSource dataSource = new DataSource();
		dataSource.setDataFormat(DSDataFormat.XML);
		dataSource.setRecordXPath("//ontologyBean");
		dataSource.setDataURL("odie_client/foundry");

		DataSourceTextField ontologyIdField = new DataSourceTextField(
				"id", "oid");
		ontologyIdField.setHidden(true) ;
		DataSourceTextField displayLabelField = new DataSourceTextField(
				"displayLabel", "Name");
		displayLabelField.setLength(45) ;
		DataSourceTextField descriptionField = new DataSourceTextField(
				"description", "Description");
		
		DataSourceTextField abbreviationField = new DataSourceTextField(
				"abbreviation", "Abbreviation") ;
		abbreviationField.setHidden(true) ;

		dataSource.setFields(ontologyIdField, displayLabelField,
				descriptionField, abbreviationField);
		
		return dataSource ;
		
	}
	
	private RecordDoubleClickHandler buildOntologyDoubleClickListener() {
		return new RecordDoubleClickHandler() {
            public void onRecordDoubleClick(RecordDoubleClickEvent event) {
            	Record record = event.getRecord() ;
            	currentOntologyId = record.getAttribute("id") ;
            	currentClsId = null ;
            	buildClsGroups() ;
            	redraw() ;
            }
        } ;
	}
	
	private void buildClsGroups() {
		if (clsLayout != null) {
			removeMember(clsLayout) ;
		}
		clsGroup = buildClsGroup("Current Cls", XPATH_CLS_PATTERN) ;
		subClsGroup = buildClsGroup("Subclasses", XPATH_SUBCLS_PATTERN) ;
		superClsGroup = buildClsGroup("Superclasses", XPATH_SUPERCLS_PATTERN) ;
		clsLayout = new HLayout() ;
		clsLayout.setMembersMargin(5);
		clsLayout.setLayoutMargin(0);
		clsLayout.addMember(superClsGroup) ;
		clsLayout.addMember(clsGroup) ;
		clsLayout.addMember(subClsGroup) ;
		addMember(clsLayout) ;
	}
	
	private VLayout buildClsGroup(String groupName, String xPathExpression) {
		VLayout groupLayout = null ;
		final ListGrid grid = buildListGrid() ;
		grid.setAlternateRecordStyles(true);
		grid.setShowAllRecords(true);
		grid.setSelectionType(SelectionStyle.SINGLE);
		grid.setCanSort(true) ;
		grid.setCanAcceptDrop(false) ;
		grid.setCanEdit(false) ;
		grid.setCanReorderRecords(false) ;
		grid.setCanFreezeFields(false) ;
		grid.setCanReorderFields(false) ;
		grid.setCanGroupBy(false) ;
		grid.setCanHover(true);
		grid.setCanSelectAll(false);
		grid.setCanSelectText(false) ;
		grid.setCanResizeFields(false) ;
		grid.setShowHeaderContextMenu(false) ;
		grid.setHoverWidth(300) ;
		grid.addDataArrivedHandler(new DataArrivedHandler() {
			public void onDataArrived(DataArrivedEvent event) {
				grid.setSortField("label") ;
				grid.sort() ;
				grid.setCanSort(false) ;
				grid.redraw();
			}}) ;
		grid.addRecordDoubleClickHandler(buildClsRecordDoubleClickListener());
		if (this.currentOntologyId != null) {
			DataSource dataSource = buildClsDataSource(currentOntologyId, currentClsId, xPathExpression) ;
			grid.setDataSource(dataSource) ;
		}	
		groupLayout = new VLayout();
		groupLayout.setLayoutMargin(5) ;
		groupLayout.setIsGroup(true);
		groupLayout.setGroupTitle(groupName);
		groupLayout.addMember(grid) ;
		return groupLayout ;
	}
	
	private RecordDoubleClickHandler buildClsRecordDoubleClickListener() {
		return new RecordDoubleClickHandler() {
            public void onRecordDoubleClick(RecordDoubleClickEvent event) {
            	Record record = event.getRecord() ;
            	currentClsId = record.getAttribute("id") ;
            	buildClsGroups() ;
            	redraw() ;
            }
        } ;
	}
	
	private DataSource buildClsDataSource(String ontologyId, String clsId, String xPathExpres) {
		DataSource dataSource = new DataSource();
		dataSource.setDataFormat(DSDataFormat.XML);
		dataSource.setRecordXPath(xPathExpres);
		String urlName = "odie_client/foundry?ontologyId=" + ontologyId ;
		if (clsId != null) {
			urlName += "&clsId=" + clsId ;
		}
		dataSource.setDataURL(urlName);
		
		DataSourceTextField clsIdField = new DataSourceTextField(
				"id", "clsId");
		clsIdField.setHidden(true) ;
		DataSourceTextField labelField = new DataSourceTextField(
				"label", "Name");

		dataSource.setFields(clsIdField, labelField);
		
		return dataSource ;
	}


	
	private ListGrid buildListGrid() {
		ListGrid grid = new ListGrid();
		grid.setWidth100();
		grid.setHeight100();
		grid.setAutoFetchData(true);
		return grid ;
	}

}
